package intelligentCustomer;

import com.knuddels.jtokkit.Encodings;
import com.knuddels.jtokkit.api.Encoding;
import com.knuddels.jtokkit.api.EncodingType;
import dev.langchain4j.agent.tool.ToolExecutionRequest;
import dev.langchain4j.agent.tool.ToolSpecification;
import dev.langchain4j.data.message.ChatMessage;
import dev.langchain4j.model.Tokenizer;
import dev.langchain4j.model.openai.OpenAiStreamingChatModel;
import dev.langchain4j.service.AiServices;
import intelligentCustomer.channel.ChannelAdapter;
import intelligentCustomer.channel.ChannelAdapterFactory;
import intelligentCustomer.intent.Intent;
import intelligentCustomer.intent.IntentRecognizer;
import intelligentCustomer.knowledge.KnowledgeBase;
import intelligentCustomer.memory.MemoryManager;
import intelligentCustomer.planning.*;
import intelligentCustomer.reasoning.ReasoningEngine;
import intelligentCustomer.session.Message;
import intelligentCustomer.session.UserSession;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 智能客服系统的主类
 * 负责协调对话处理、会话管理、意图识别和知识库检索等核心功能
 */
public class IntelligentCustomer {
    
    /** AI客服代理接口，用于生成回复 */
    private final CustomerServiceAgent agent;
    
    /** 用户会话管理，保存每个用户的对话历史和状态 */
    private final Map<String, UserSession> sessions = new HashMap<>();
    
    /** 知识库，包含产品信息和常见问题解答 */
    private final KnowledgeBase knowledgeBase;
    
    /** 意图识别器，用于分析用户问题的意图 */
    private final IntentRecognizer intentRecognizer;
    
    /** 记忆管理器，处理用户长期记忆 */
    private final MemoryManager memoryManager;
    
    /** 自适应规划器 */
    private final AdaptivePlanner planner;
    
    /** 推理引擎 */
    private final ReasoningEngine reasoningEngine;
    
    /** 大语言模型，用于生成回复和进行推理 */
    private final OpenAiStreamingChatModel model;

    /**
     * 定义DeepSeek特有的Tokenizer
     */
    public class DeepSeekTokenizer implements Tokenizer {
        private final Encoding encoding;

        public DeepSeekTokenizer() {
            // 假设 DeepSeek 使用 cl100k_base，或替换为实际编码
            this.encoding = Encodings.newDefaultEncodingRegistry().getEncoding(EncodingType.CL100K_BASE);
        }

        @Override
        public int estimateTokenCountInText(String s) {
            return encoding.countTokens(s);
        }

        @Override
        public int estimateTokenCountInMessage(ChatMessage chatMessage) {
            return encoding.countTokens(chatMessage.text());
        }

        @Override
        public int estimateTokenCountInMessages(Iterable<ChatMessage> iterable) {
            return encoding.countTokens(iterable.iterator().next().text());
        }

        @Override
        public int estimateTokenCountInToolSpecifications(Iterable<ToolSpecification> iterable) {
            return 0;
        }

        @Override
        public int estimateTokenCountInToolExecutionRequests(Iterable<ToolExecutionRequest> iterable) {
            return 0;
        }
    }

    // 使用自定义 Tokenizer
    Tokenizer deepSeekTokenizer = new DeepSeekTokenizer();
    /**
     * 构造函数
     */
    public IntelligentCustomer() {
        // 初始化语言模型
        model = OpenAiStreamingChatModel.builder()
                .apiKey("xxxx")
                .baseUrl("https://api.deepseek.com/v1")
                .modelName("deepseek-chat")
                .tokenizer(deepSeekTokenizer)
                .build();

//        model = OpenAiStreamingChatModel.builder()
//                .apiKey("xxxx")
//                .baseUrl("https://api.aiproxy.io/v1")
//                .modelName("gpt-4")
//                .temperature(0.7)
//                .build();
        
        // 初始化AI客服代理
        agent = AiServices.builder(CustomerServiceAgent.class)
                .streamingChatLanguageModel(model)
                .build();
        
        // 初始化知识库
        knowledgeBase = new KnowledgeBase();
        
        // 初始化意图识别器
        intentRecognizer = new IntentRecognizer(model);
        
        // 初始化记忆管理器
        memoryManager = new MemoryManager();
        
        // 初始化推理引擎
        reasoningEngine = new ReasoningEngine(model);
        
        // 初始化自适应规划器
        planner = new AdaptivePlanner(model);
    }
    
    /**
     * 处理用户查询并生成回复
     * 
     * @param userId 用户唯一标识
     * @param query 用户查询内容
     * @return 系统生成的回复
     */
    public String processQuery(String userId, String query) {
        // 获取或创建用户会话
        UserSession session = getOrCreateSession(userId);
        
        // 记录用户查询到会话历史
        session.addMessage(new Message("用户", query, LocalDateTime.now()));
        
        try {

            // 使用带回调的意图识别
            Intent intent = intentRecognizer.recognizeIntent(query, reasoningStep -> {
                // 将推理步骤保存到会话中
                session.setAttribute("intentReasoningSteps", session.getAttribute("intentReasoningSteps") + "\n" + reasoningStep);
                // 如果开启了调试模式，实时输出推理步骤
                if (isDebugMode(userId)) {
                    System.out.println("[意图识别] " + reasoningStep);
                }
            });
            
            // 创建规划上下文
            PlanningContext context = new PlanningContext(query, intent, session);
            
            // 创建基于推理的执行计划
            Plan plan = planner.createReasoningBasedPlan(context, reasoningEngine);
            
            // 执行计划
            PlanResult planResult = planner.executePlan(plan, context);
            
            // 保存执行结果到会话
            session.setAttribute("lastPlanResult", planResult);
            
            String response;
            if (planResult.isSuccessful()) {
                response = planResult.getFinalResponse();
            } else {
                // 如果计划执行失败，使用基础对话能力
                String relevantKnowledge = knowledgeBase.retrieveRelevantInfo(query, intent.getCategory());
                // 将会话历史转换为字符串
                String historyText = convertHistoryToString(session.getHistory());
                response = agent.chat(historyText, query, relevantKnowledge);
            }
            
            // 更新会话历史
            session.addMessage(new Message("系统", response, LocalDateTime.now()));
            
            // 更新用户记忆
            memoryManager.updateMemory(userId, session);
            
            return response;
            
        } catch (Exception e) {
            String errorResponse = "抱歉，系统处理您的请求时遇到了问题，请稍后再试。";
            session.addMessage(new Message("系统", errorResponse, LocalDateTime.now()));
            e.printStackTrace();
            return errorResponse;
        }
    }
    
    /**
     * 获取或创建用户会话
     * 
     * @param userId 用户唯一标识
     * @return 用户会话对象
     */
    private UserSession getOrCreateSession(String userId) {
        return sessions.computeIfAbsent(userId, k -> new UserSession(userId));
    }
    
    /**
     * 从特定渠道处理用户查询
     * 
     * @param channelType 渠道类型
     * @param userId 用户唯一标识
     * @param query 用户查询
     * @return 系统回复
     */
    public String processQueryFromChannel(String channelType, String userId, String query) {
        // 获取渠道适配器
        ChannelAdapter adapter = ChannelAdapterFactory.getAdapter(channelType);
        
        // 处理输入消息
        String processedQuery = adapter.processIncomingMessage(query);
        
        // 处理查询
        String response = processQuery(userId, processedQuery);
        
        // 格式化输出消息
        return adapter.formatOutgoingMessage(response);
    }
    
    /**
     * 结束并保存用户会话
     * 
     * @param userId 用户唯一标识
     */
    public void endSession(String userId) {
        UserSession session = sessions.remove(userId);
        if (session != null) {
            // 保存会话历史到长期记忆
            memoryManager.saveSessionHistory(userId, session.getHistory());
        }
    }
    
    /**
     * 开启调试模式
     * 
     * @param userId 用户唯一标识
     * @param enabled 是否启用
     */
    public void setDebugMode(String userId, boolean enabled) {
        UserSession session = getOrCreateSession(userId);
        session.setDebugMode(enabled);
    }
    
    /**
     * 获取最后一次计划执行的详细信息
     * 
     * @param userId 用户唯一标识
     * @return 计划执行详细信息
     */
    public String getLastPlanDetails(String userId) {
        UserSession session = getOrCreateSession(userId);
        PlanResult lastPlan = (PlanResult) session.getAttribute("lastPlanResult");
        if (lastPlan != null) {
            return lastPlan.getExecutionDetails();
        }
        return "没有可用的计划执行记录";
    }
    
    /**
     * 将会话历史转换为字符串
     * 
     * @param history 会话历史列表
     * @return 格式化的会话历史字符串
     */
    private String convertHistoryToString(List<Message> history) {
        StringBuilder sb = new StringBuilder();
        for (Message message : history) {
            sb.append(message.getRole()).append(": ")
              .append(message.getContent()).append("\n");
        }
        return sb.toString();
    }
    
    /**
     * 构建对话上下文
     * 
     * @param session 用户会话
     * @return 构建的上下文字符串
     */
    @SuppressWarnings("unused")
    private String buildContext(UserSession session) {
        StringBuilder context = new StringBuilder();
        List<Message> history = session.getHistory();
        
        // 使用最近的5条消息构建上下文
        int startIndex = Math.max(0, history.size() - 10);
        for (int i = startIndex; i < history.size(); i++) {
            Message message = history.get(i);
            context.append(message.getRole()).append(": ").append(message.getContent()).append("\n");
        }
        
        return context.toString();
    }
    
    /**
     * 检查用户是否开启了调试模式
     * 
     * @param userId 用户唯一标识
     * @return 是否开启调试模式
     */
    private boolean isDebugMode(String userId) {
        UserSession session = getOrCreateSession(userId);
        Boolean debugMode = (Boolean) session.getAttribute("debugMode");
        return debugMode != null && debugMode;
    }
    
    /**
     * 主方法，用于测试和演示
     */
    public static void main(String[] args) {
        IntelligentCustomer customerService = new IntelligentCustomer();
        
        // 测试用户ID
        String userId = "user123";
        
        // 开启调试模式
        customerService.setDebugMode(userId, true);
        
        // 示例对话
        String query1 = "你们有什么新款手机推荐？";
        String response1 = customerService.processQuery(userId, query1);
        System.out.println("用户: " + query1);
        System.out.println("智能助手: " + response1);
        System.out.println("计划执行详情: " + customerService.getLastPlanDetails(userId));
        System.out.println();
        
        String query2 = "这款手机的电池续航怎么样？";
        String response2 = customerService.processQuery(userId, query2);
        System.out.println("用户: " + query2);
        System.out.println("智能助手: " + response2);
        System.out.println("计划执行详情: " + customerService.getLastPlanDetails(userId));
        System.out.println();
        
        String query3 = "我想了解一下你们的退货政策";
        String response3 = customerService.processQuery(userId, query3);
        System.out.println("用户: " + query3);
        System.out.println("智能助手: " + response3);
        System.out.println("计划执行详情: " + customerService.getLastPlanDetails(userId));
        System.out.println();
        
        // 从不同渠道接入
        String wechatQuery = "如何查询我的订单状态?";
        String wechatResponse = customerService.processQueryFromChannel("wechat", "wxuser001", wechatQuery);
        System.out.println("微信用户: " + wechatQuery);
        System.out.println("智能助手(微信): " + wechatResponse);
        
        // 结束会话
        customerService.endSession(userId);
    }
}